package http.DataUtil.file;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class FileUtil {
	@SuppressWarnings("unused")
	private static final String TEXT_ENCODING = "UTF-8";
	public static final String STR_AUDIO = "audio";
	public static final String STR_VIDEO = "video";
	public static final String STR_APK = "apk";
	public static final String STR_IMAGE = "image";
	public static final String BACKUP_TO_SDCARD_PATH = Environment
			.getExternalStorageDirectory() + "/data/backup/";

	public static final String BACKUP_TO_TIME = Environment
			.getExternalStorageDirectory() + "/data/backup/backup";

	public static final String BACKUPUSERINFO_SDCARD_PATH = Environment
			.getExternalStorageDirectory() + "/data/cache";

	public static final String LAUNCHLOGO_PATH = Environment
			.getExternalStorageDirectory() + "/data/cache/launchlogo";

	public static final String BACKUP_TO_USERINFO = Environment
			.getExternalStorageDirectory() + "/data/cache/backupinfo";

	public static final String CACHE_LRC = Environment
			.getExternalStorageDirectory() + "/data/cache/lrc/";

	public static final String CACHE_DB = Environment
			.getExternalStorageDirectory() + "/data/cache/";
	public static final String ENCODE_UTF8 = "UTF-8";
	public static final String ENCODE_ANSI = "GB2312";
	@SuppressWarnings("unused")
	private static final int SECTION_LENGTH = 2048;
	private static final int SKIP_MAX = 256;

	public static int getFilePageNumber(String path) {
		File file = new File(path);

		if (!file.exists()) {
			return 0;
		}
		long length = file.length();
		long mod = length % 2048L;
		if (mod > 0L) {
			mod = 2048L - mod;
		}

		return (int) ((length + mod) / 2048L);
	}

	public static String readFileSection(String path, String encode, int page)
			throws IOException {
		File file = new File(path);
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(
				file));
		in.skip(page * 2048);
		byte[] readBytes = new byte[4096];
		in.read(readBytes, 0, 4096);
		in.close();

		int index1 = getIndexOfEnter(readBytes, 0);
		int index2 = getIndexOfEnter(readBytes, 2048);
		int count = 2048;
		int start = 0;
		if ((index1 != -1) && (page != 0) && (index1 <= SKIP_MAX)) {
			count -= index1;
			start = index1 + 1;
		}
		if ((index2 != -1) && (index2 - 2048 <= SKIP_MAX)) {
			count += index2 - 2048;
		}

		byte[] retBytes = new byte[count];
		for (int i = 0; i < count; start++) {
			retBytes[i] = readBytes[start];

			i++;
		}

		String ret = new String(retBytes, encode);

		return ret;
	}

	private static int getIndexOfEnter(byte[] temp, int start) {
		int i = start;
		for (int length = temp.length; i < length; i++) {
			if (temp[i] == 10) {
				return i;
			}
		}

		return -1;
	}

	public static boolean isEndFileSection(String path, String encode, int page)
			throws IOException {
		File file = new File(path);
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(
				file));
		in.skip(page * 2048);
		byte[] temp = new byte[2048];
		int readSize = in.read(temp, 0, 2048);
		in.close();

		return readSize < 2048;
	}

	public static String getCharset(File file) {
		String charset = "GB2312";
		byte[] first3Bytes = new byte[3];
		try {
			boolean checked = false;
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(file));
			bis.mark(0);
			int read = bis.read(first3Bytes, 0, 3);
			if (read == -1) {
				return charset;
			}

			if ((first3Bytes[0] == -1) && (first3Bytes[1] == -2)) {
				charset = "UTF-16LE";
				checked = true;
			} else if ((first3Bytes[0] == -2) && (first3Bytes[1] == -1)) {
				charset = "UTF-16BE";
				checked = true;
			} else if ((first3Bytes[0] == -17) && (first3Bytes[1] == -69)
					&& (first3Bytes[2] == -65)) {
				charset = "UTF-8";
				checked = true;
			}

			if (!checked) {
				int loc = 0;
				while ((read = bis.read()) != -1) {
					loc++;
					if (read >= 240)
						break;
					if ((128 <= read) && (read <= 191))
						break;
					if ((192 <= read) && (read <= 223)) {
						read = bis.read();
						if ((128 > read) || (read > 191)) {
							break;
						}
					} else if ((224 <= read) && (read <= 239)) {
						read = bis.read();
						if ((128 > read) || (read > 191))
							break;
						read = bis.read();
						if ((128 > read) || (read > 191))
							break;
						charset = "UTF-8";
						break;
					}

				}

			}

			bis.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return charset;
	}

	public static boolean checkDirPath(String newName) {
		boolean ret = false;
		if (newName.indexOf("\\") == -1) {
			ret = true;
		}
		return ret;
	}

	public static boolean checkFilePath(String newName) {
		boolean ret = false;
		if (newName.indexOf("\\") == -1) {
			ret = true;
		}
		return ret;
	}

	public static String getFileName(String path) {
		String name = "";
		try {
			name = path.substring(path.lastIndexOf("/") + 1,
					path.lastIndexOf("."));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return name;
	}

	public static String fileSizeMsg(File f) {
		int sub_index = 0;
		String show = "";
		if (f.isFile()) {
			long length = f.length();
			if (length >= 1073741824L) {
				sub_index = String.valueOf((float) length / 1.073742E+009F)
						.indexOf(".");
				show = new StringBuilder(
						String.valueOf((float) length / 1.073742E+009F))
						.append("000").toString().substring(0, sub_index + 3)
						+ "GB";
			} else if (length >= 1048576L) {
				sub_index = String.valueOf((float) length / 1048576.0F)
						.indexOf(".");
				show = new StringBuilder(
						String.valueOf((float) length / 1048576.0F))
						.append("000").toString().substring(0, sub_index + 3)
						+ "MB";
			} else if (length >= 1024L) {
				sub_index = String.valueOf((float) length / 1024.0F).indexOf(
						".");
				show = new StringBuilder(
						String.valueOf((float) length / 1024.0F)).append("000")
						.toString().substring(0, sub_index + 3)
						+ "KB";
			} else if (length < 1024L) {
				show = String.valueOf(length) + "B";
			}
		}
		return show;
	}

	public static String fileSizeMsg(long length) {
		int sub_index = 0;
		String show = "";

		if (length >= 1073741824L) {
			sub_index = String.valueOf((float) length / 1.073742E+009F)
					.indexOf(".");
			show = new StringBuilder(
					String.valueOf((float) length / 1.073742E+009F))
					.append("000").toString().substring(0, sub_index + 2)
					+ "GB";
		} else if (length >= 1048576L) {
			sub_index = String.valueOf((float) length / 1048576.0F)
					.indexOf(".");
			show = new StringBuilder(
					String.valueOf((float) length / 1048576.0F)).append("000")
					.toString().substring(0, sub_index + 2)
					+ "MB";
		} else if (length >= 1024L) {
			sub_index = String.valueOf((float) length / 1024.0F).indexOf(".");
			show = new StringBuilder(String.valueOf((float) length / 1024.0F))
					.append("000").toString().substring(0, sub_index + 2)
					+ "KB";
		} else if (length < 1024L) {
			show = String.valueOf(length) + "B";
		}
		return show;
	}

	public static Bitmap fitSizePic(File f) {
		Bitmap resizeBmp = null;
		BitmapFactory.Options opts = new BitmapFactory.Options();

		if (f.length() < 20480L)
			opts.inSampleSize = 1;
		else if (f.length() < 51200L)
			opts.inSampleSize = 2;
		else if (f.length() < 307200L)
			opts.inSampleSize = 4;
		else if (f.length() < 819200L)
			opts.inSampleSize = 6;
		else if (f.length() < 1048576L)
			opts.inSampleSize = 8;
		else {
			opts.inSampleSize = 10;
		}
		resizeBmp = BitmapFactory.decodeFile(f.getPath(), opts);
		return resizeBmp;
	}

	public static String getFileSuffix(String filePath) {
		try {
			return filePath.substring(filePath.lastIndexOf("."),
					filePath.length()).toLowerCase();
		} catch (Exception e) {
		}
		return "";
	}

	public static String getMIMEType(File f, boolean isOpen) {
		String type = "";
		String fName = f.getName();

		String end = fName
				.substring(fName.lastIndexOf(".") + 1, fName.length())
				.toLowerCase();
		if (isOpen) {
			if ((end.equals("m4a")) || (end.equals("mp3"))
					|| (end.equals("mid")) || (end.equals("xmf"))
					|| (end.equals("ogg")) || (end.equals("wav")))
				type = "audio";
			else if ((end.equals("3gp")) || (end.equals("mp4")))
				type = "video";
			else if ((end.equals("jpg")) || (end.equals("gif"))
					|| (end.equals("png")) || (end.equals("jpeg"))
					|| (end.equals("bmp"))) {
				type = "image";
			} else {
				type = "*";
			}
			type = type + "/*";
		} else if ((end.equals("m4a")) || (end.equals("mp3"))
				|| (end.equals("mid")) || (end.equals("xmf"))
				|| (end.equals("ogg")) || (end.equals("wav"))) {
			type = "audio";
		} else if ((end.equals("3gp")) || (end.equals("mp4"))) {
			type = "video";
		} else if ((end.equals("jpg")) || (end.equals("gif"))
				|| (end.equals("png")) || (end.equals("jpeg"))
				|| (end.equals("bmp"))) {
			type = "image";
		} else if (end.equals("apk")) {
			type = "apk";
		}

		return type;
	}

	public static boolean delFile(File f) {
		boolean ret = false;
		if (f.exists()) {
			f.delete();
			ret = true;
		}
		return ret;
	}

	public static boolean deleteFile(String filePath) {
		return delFile(new File(filePath));
	}

	public static String availableSpare() {
		return fileSizeMsg(availableSdcardSpace());
	}

	public static int usedSdcardProgress() {
		long total = 0L;
		if ((total = totalSdcardSpace()) != 0L) {
			return (int) ((total - availableSdcardSpace()) * 100L / total);
		}
		return 0;
	}

	public static long totalSdcardSpace() {
		File external = Environment.getExternalStorageDirectory();
		if (!external.exists()) {
			return 0L;
		}
		StatFs statfs = new StatFs(external.getPath());
		long blockCount = statfs.getBlockCount();
		long blockSize = statfs.getBlockSize();
		return blockCount * blockSize;
	}

	public static long availableSdcardSpace() {
		File external = Environment.getExternalStorageDirectory();
		if (!external.exists()) {
			return 0L;
		}
		StatFs statfs = new StatFs(external.getPath());
		long availableBlocks = statfs.getAvailableBlocks();
		long blockSize = statfs.getBlockSize();
		return availableBlocks * blockSize;
	}

	public static String availableDataSpare() {
		return fileSizeMsg(availableData());
	}

	public static int userdDataSpareProgress() {
		long total = 0L;
		if ((total = getTotalDataSpare()) != 0L) {
			return (int) ((total - availableData()) * 100L / total);
		}
		return 0;
	}

	public static long getTotalDataSpare() {
		File external = Environment.getDataDirectory();
		if (!external.exists()) {
			return 0L;
		}
		StatFs statfs = new StatFs(external.getPath());
		long blockSize = statfs.getBlockSize();
		long blockCount = statfs.getBlockCount();
		return blockSize * blockCount;
	}

	public static long availableData() {
		File external = Environment.getDataDirectory();
		if (!external.exists()) {
			return 0L;
		}
		StatFs statfs = new StatFs(external.getPath());
		long availableBlocks = statfs.getAvailableBlocks();
		long blockSize = statfs.getBlockSize();
		return availableBlocks * blockSize;
	}

	public static void initFileDir() {
		File f = new File("/sdcard");
		if (f.exists()) {
			f = new File(Environment.getExternalStorageDirectory()
					+ "/data/cache/image/");
			if (!f.exists()) {
				f.mkdirs();
			}
			File lrc = new File(CACHE_LRC);
			if (lrc.exists())
				return;
			f.mkdirs();
		} else {
			return;
		}
	}

	public static void craeteFile(String path, byte[] bytes) {
		File f = new File(path);
		if (!f.exists()) {
			try {
				f.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
		FileOutputStream fout = null;
		try {
			fout = new FileOutputStream(f);
			fout.write(bytes);
			fout.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static boolean isEixstsFile(String path) {
		File f = new File(path);

		return f.exists();
	}

	public static boolean isApkFile(String path) {
		try {
			return path.substring(path.lastIndexOf(".") + 1, path.length())
					.toLowerCase().equals("apk");
		} catch (Exception e) {
		}
		return false;
	}

	public static String readFile(String path) {
		String str = "";
		try {
			File file = new File(path);
			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));
			int length = (int) file.length();
			byte[] temp = new byte[length];
			in.read(temp, 0, length);
			str = new String(temp, "UTF-8");
			in.close();
		} catch (IOException localIOException) {
		}
		return str;
	}

	public static byte[] getFileContent(String filePath) {
		try {
			File file = new File(filePath);

			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));
			int length = (int) file.length();
			byte[] temp = new byte[length];
			in.read(temp, 0, length);
			in.close();
			return temp;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static boolean isApkFile(File file) {
		return "apk".equals(getMIMEType(file, false));
	}

	public static boolean isExistSdCard() {
		try {
			if (Environment.getExternalStorageState().equals("mounted"))
				return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static String getDBDirPath(Context context) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("/data/data/");
		buffer.append(context.getPackageName());
		buffer.append("/databases/");
		return buffer.toString();
	}

	public static boolean copyFile(String oldPath, String newPath) {
		try {
			int bytesum = 0;
			int byteread = 0;
			String f_new = "";
			File f_old = new File(oldPath);
			if (newPath.endsWith(File.separator))
				f_new = newPath + f_old.getName();
			else {
				f_new = newPath + File.separator + f_old.getName();
			}
			new File(newPath).mkdirs();
			new File(f_new).createNewFile();

			if (f_old.exists()) {
				InputStream inStream = new FileInputStream(oldPath);
				FileOutputStream fs = new FileOutputStream(f_new);
				byte[] buffer = new byte[1444];
				while ((byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread;
					fs.write(buffer, 0, byteread);
				}
				inStream.close();
				fs.flush();
				fs.close();
			}
		} catch (Exception e) {
			return false;
		}

		return true;
	}

	public static boolean createNewDir(String path) {
		try {
			File file = new File(path);
			return file.mkdirs();
		} catch (Exception e) {
		}
		return false;
	}

	public static String getFileNames(String filePath) {
		File file = new File(filePath);
		return file.getName();
	}

	public static String getFilePath(String filePath) {
		File file = new File(filePath);
		return file.getAbsolutePath();
	}

	public static List<String> getFileDirList(String filePath) {
		List<String> paths = new ArrayList<String>();
		File f = new File(filePath);
		File[] files = f.listFiles();
		String _filePath = null;
		if (files != null) {
			int length = files.length;
			for (int i = 0; i < length; i++) {
				_filePath = files[i].getPath();
				if (isDirectory(_filePath)) {
					paths.add(_filePath);
				}
			}
		}
		return paths;
	}

	public static boolean isDirectory(String filePath) {
		File file = new File(filePath);

		return file.isDirectory();
	}
}
